import { Building } from "../buildings";
import type { Tile, City } from "..";
import type { PowerPlant } from "../buildings";

type TypePowerPlantObject = {
    powerPlant: PowerPlant,
    frontier: Array<Tile>;
    visited: { [key: string]: Boolean; };
};

export class PowerService {

    simulate(city: City) {

        // 找到城市中所有的发电站,并且重置电力分配
        const powerPlantList = this.trackAndReset(city);

        if (powerPlantList.length === 0) return;


        // 以每个发电站执行广度优先算法来分配电力
        let searching = true;

        while (searching) {

            searching = false;

            for (let i = 0; i < powerPlantList.length; i++) {

                const powerPlantObject = powerPlantList[i];
                const { powerPlant, frontier, visited } = powerPlantObject;

                // 如果发电站没有电力了,跳过计算
                if (powerPlant.powerAvailable === 0) continue;

                if (frontier.length > 0) {

                    searching = true;

                    const tile = frontier.shift();
                    const building = tile.building;

                    // 记录搜索过的网格
                    visited[tile.name] = true;

                    // 如果网格上的建筑需要电力
                    if (building.power.supplied < building.power.required) {

                        // 获取可分配电力
                        const powerSupplied = Math.min(powerPlant.powerAvailable, building.power.needed);
                        powerPlant.powerConsumed += powerSupplied;
                        building.power.supplied += powerSupplied;
                    }

                    const { x, y } = tile;

                    const left = city.getTile(x - 1, y);
                    const right = city.getTile(x + 1, y);
                    const top = city.getTile(x, y - 1);
                    const bottom = city.getTile(x, y + 1);

                    if (needSearch(left, visited)) {
                        frontier.push(left);
                    }
                    if (needSearch(right, visited)) {
                        frontier.push(right);
                    }
                    if (needSearch(top, visited)) {
                        frontier.push(top);
                    }
                    if (needSearch(bottom, visited)) {
                        frontier.push(bottom);
                    }
                }
            }

        }

        function needSearch(tile: Tile, visited: { [key: string]: Boolean; }): boolean {

            return tile && !visited[tile.name] && !!tile.building;

        }
    }


    /** 收集城市中所有的发电站，并且重置电力分配 */
    private trackAndReset(city: City): Array<TypePowerPlantObject> {

        const powerPlantList: TypePowerPlantObject[] = [];

        for (let x = 0; x < city.size; x++) {

            for (let y = 0; y < city.size; y++) {

                const tile = city.getTile(x, y);
                const building = tile.building;

                if (building) {
                    if (building.type === Building.type.powerPlant) {

                        // 将每个电站的消耗电力重置为0
                        const powerPlant = building as PowerPlant;
                        powerPlant.powerConsumed = 0;

                        powerPlantList.push({
                            powerPlant,
                            frontier: [tile],
                            visited: {}
                        });

                    } else {

                        // 重置电力分配
                        building.power.supplied = 0;
                    }
                }
            }

        }

        return powerPlantList;
    }



}